#!/usr/bin/python
# -*- coding: utf-8 -*-

#  date 2013/2/17
#  name commonScripts
#  author lizhi
#  E_mail  guishiye@sina.cn
#  QQ  294596787

import maya.cmds as mc
import maya.OpenMaya as om
import sys
import math
import maya.mel as mel
#----------------------   make zero group  ------------------------------
class commonScripts(object):
    def __init__(self):
        pass

    def replaceShape(self,oldCtrl,newCtrl):
        childdrenShape=mc.listRelatives(oldCtrl,s=True)
        for i in childdrenShape:
            ctrlname=mc.duplicate(i)[0]
            ctrlshapename=mc.listRelatives(ctrlname,s=True)[0]

            mc.parent(ctrlshapename,newCtrl,shape=True,add=True)
            mc.delete(ctrlname)
            mc.delete(i)
            
    def makeZeroGrp(self,sufname='zero',Mode=0):
    #   mode == o:  replace;  mode == 1:  add  
        seleobj=mc.ls(sl=True)
        for i in seleobj:
            if Mode==0:
                groupname=str(i)+sufname
            if Mode==1:
                regName=str(i).split('_')
                groupname=str(i).replace(regName[-1],sufname)
            mc.group(n=groupname,em=True)
            parent=mc.listRelatives(i,p=True)
            mc.parentConstraint(i,groupname,mo=False,n='needDeleteConstriant',w=1)
            mc.delete('needDeleteConstriant')
            mc.parent(i,groupname)
            if parent==None:
                pass
            else:
                mc.parent(groupname,parent)
            
                
    #----------------------   make zero group base know objection ------------------------------
    def makeZeroGrpTwo(self,sufname='zero',cenObj='',Mode=0):
    #   mode == o:  replace;  mode == 1:  add  
        seleobj=mc.ls(sl=True)
        for i in seleobj:
            if cenObj=='':
                cenParent=i
            else:
                cenParent=cenObj
            if Mode==0:
                groupname=str(i)+sufname
            if Mode==1:
                regName=str(i).split('_')
                groupname=str(i).replace(regName[-1],sufname)
            mc.group(n=groupname,em=True)
            parent=mc.listRelatives(i,p=True)
            mc.parentConstraint(cenParent,groupname,mo=False,n='needDeleteConstriant',w=1)
            mc.delete('needDeleteConstriant')
            mc.parent(i,groupname)
            if parent==None:
                pass
            else:
                mc.parent(groupname,parent)
        return(groupname)
    #----------------------   get Type of Object  ------------------------------
    def getObjType(self,objCheck):
        try:
            childobj=mc.listRelatives(objCheck,c=True)[0]
            typelist=mc.nodeType(childobj, api=True )
            return(typelist)
        except:
            sys.stdout.write('the object selected has no shapeNode...')
            
    def getTypeObject(self,tpye='kLocator',objectsel=[]):     
        locatorWants=[]
    
        for k in objectsel:
            try:
                childobj=mc.listRelatives(k,c=True)
                for m in childobj:
                    typelist=mc.nodeType(m, api=True )
                    if typelist=='kTransform':
                        pass
                    else:
                        if typelist==tpye:
                            locatorWants.append(k)
            except:
                pass        
        if len(locatorWants)==0:
            sys.stdout.write('No objects matching requirements......')
        else:
            mc.select(locatorWants)
        return(locatorWants)
    
    #----------------------   mirror Locator of facial ------------------------------    
    def mirrorLocator(self,mirror=1):
        if mirror==2:
            
            # Mirror facial ctrl
            mc.select('facial_R_*_locator',r=True)
            mc.select('Mouth_R_*_locator',add=True)
            
            objectName=mc.ls(sl=True)
            num=len(objectName)
            for i in range(num):
                selObjTra=mc.xform(objectName[i],q=True,t=True)
                selObjRot=mc.xform(objectName[i],q=True,ro=True)
                reg='_R_'
                mirObj=objectName[i].replace(reg,'_L_')
                mc.setAttr(str(mirObj)+'.t',-1*selObjTra[0],selObjTra[1],selObjTra[2])
                mc.setAttr(str(mirObj)+'.r',selObjRot[0],-1*selObjRot[1],-1*selObjRot[2])
                mc.select(objectName,r=True)
                
            mc.select(cl=True)
            
        if mirror==1:
            
            # Mirror facial ctrl
            mc.select('facial_L_*_locator',r=True)
            mc.select('Mouth_L_*_locator',add=True)
            
            objectName=mc.ls(sl=True)
            num=len(objectName)
            for i in range(num):
                selObjTra=mc.xform(objectName[i],q=True,t=True)
                selObjRot=mc.xform(objectName[i],q=True,ro=True)
                reg='_L_'
                mirObj=objectName[i].replace(reg,'_R_')
                mc.setAttr(str(mirObj)+'.t',-1*selObjTra[0],selObjTra[1],selObjTra[2])
                mc.setAttr(str(mirObj)+'.r',selObjRot[0],-1*selObjRot[1],-1*selObjRot[2])
                mc.select(objectName,r=True)
                
            mc.select(cl=True)
            
        print (" succesfully Mirror!\n")
    
    
    #----------------------   add attribute (float) ------------------------------    
    def addAttrs(self,objname=[''],attrname='fuck',dv=0,key=1):
        if objname==None:
            objs=mc.ls(sl=True)
        if objname!=None:
            objs=objname
            
        for i in objs:
    
            mc.addAttr(i,longName=attrname,defaultValue=dv,k=1)
            if key == 0:
                mc.setAttr(str(i)+'.'+attrname,l=True)
                
    #----------------------   add attribute (enum) ------------------------------    
    def addEnumAttr(self,objname=['nurbsSphere1'],attrname='fuck',enumMember='fuck:',key=0):
        if objname==None:
            objs=mc.ls(sl=True)
        if objname!=None:
            objs=objname
            
        for i in objs:
            mc.addAttr(i,longName=attrname,at='enum',en=enumMember,k=1)
            if key == 0:
                mc.setAttr(str(i)+'.'+attrname,l=True)
                
    #----------------------   lock attribute ------------------------------    
    def lockAttrs(self,lockattrname='demenIt'):
        mc.setAttr(lockattrname,l=True,k=False)
        
    def LZ_creatJoint(self,parentConsobj,jntname):
        mc.select(cl=True)
        mc.joint(n=jntname)
        mc.parentConstraint(parentConsobj,jntname,mo=False,n='templeconstraint')
        mc.delete('templeconstraint')
        secjntRX=mc.getAttr(str(jntname)+'.rx')
        secjntRY=mc.getAttr(str(jntname)+'.ry')
        secjntRZ=mc.getAttr(str(jntname)+'.rz')
        
        mc.setAttr(str(jntname)+'.jointOrient',secjntRX,secjntRY,secjntRZ)
        mc.setAttr(str(jntname)+'.rotate',0,0,0)
        #------------------------  create single Eyectrl -------------------------
    def createsingleEyectrl(self,curveName):
        if mc.objExists(curveName)== False:
            mc.curve(d=1,p=[(-1,0,0),(1,0,0)],k=[0,1],n='TempleCurve')
            mc.curve(d=1,p=[(0,1,0),(0,-1,0)],k=[0,1],n=curveName)
            temShapename=mc.listRelatives('TempleCurve',s=True)[0]
            mc.parent(temShapename,curveName,s=True,add=True)
            mc.delete('TempleCurve')
        else:
            sys.stdout.write('please give a unexist name')
        ###### ------------------------ get Objection World position ----------------------    
    def getWorldPosition(self,objname):
        positionWorld=mc.xform(objname,q=True,ws=True,t=True)
        return(positionWorld)
    def disBetweenPoints(self,posOne=[0,0,0],posTwo=[1,1,1]):
        disBetween=math.sqrt((posTwo[0]-posOne[0])**2+(posTwo[1]-posOne[1])**2+(posTwo[2]-posOne[2])**2)
        return(disBetween)
        
    #=================================================================================================
    #-------------------   ctrlMakerToFacial   --------------------------------
    def ctrlmakeToFacial(self,curvename):
        ctrlname=str(curvename)+'add'
        ctrladd=str(curvename).replace('_jnt','_ctrl')
        mc.curve(d=1,p=[(-0.5,0.5,0.5),(-0.5,0.5,-0.5),(0.5,0.5,-0.5),(0.5,0.5,0.5),(-0.5,0.5,0.5),(-0.5,-0.5,0.5),(0.5,-0.5,0.5),(0.5,0.5,0.5),(0.5,0.5,-0.5),(0.5,-0.5,-0.5 ),(0.5,-0.5,0.5),(-0.5,-0.5,0.5),(-0.5,-0.5,-0.5),(0.5,-0.5,-0.5),(0.5,0.5,-0.5),(-0.5,0.5,-0.5),(-0.5,-0.5,-0.5)],k=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],n=ctrlname)
        ctrlnameshape=mc.listRelatives(ctrlname,s=True)
        mc.parent(ctrlnameshape,ctrladd,add=True,s=True)
        mc.delete(ctrlname)
        shapeold=mc.listRelatives(ctrladd,s=True)
        mc.rename(shapeold,str(ctrladd)+'Shape')
        
        
        
        
    def scaleCurveHull(self,curvename,scalX,scalY,scalZ):
        curveshape=mc.listRelatives(curvename,s=True)[0]
        spans=mc.getAttr(str(curveshape)+'.spans')
        degree=mc.getAttr(str(curveshape)+'.degree')
        pointsMounts=spans+degree
        cvAllX=[]
        cvAllY=[]
        cvAllZ=[]
        for i in range(pointsMounts):
            pointcvPos=mc.xform(str(curvename)+'.cv['+str(i)+']',q=True,t=True,ws=True)
            cvAllX.append(pointcvPos[0])
            cvAllY.append(pointcvPos[1])
            cvAllZ.append(pointcvPos[2])
            
        pointCVposXMin=cvAllX[0]
        pointCVposYMin=cvAllY[0]
        pointCVposZMin=cvAllZ[0]
        
        pointCVposXMax=cvAllX[0]
        pointCVposYMax=cvAllY[0]
        pointCVposZMax=cvAllZ[0]
        
        for k in range(pointsMounts-1):
            pointCVposXMin=min(pointCVposXMin,cvAllX[k+1])
            pointCVposXMax=max(pointCVposXMax,cvAllX[k+1])
            
            pointCVposYMin=min(pointCVposYMin,cvAllY[k+1])
            pointCVposYMax=max(pointCVposYMax,cvAllY[k+1])
            
            pointCVposZMin=min(pointCVposZMin,cvAllZ[k+1])
            pointCVposZMax=max(pointCVposZMax,cvAllZ[k+1])

        centerPivetX=(pointCVposXMin+pointCVposXMax)/2
        centerPivetY=(pointCVposYMin+pointCVposYMax)/2
        centerPivetZ=(pointCVposZMin+pointCVposZMax)/2
        
        centerPivet=[centerPivetX,centerPivetY,centerPivetZ]
        
        mc.select(str(curvename)+'.cv[0:'+str((pointsMounts-1))+']')
        mc.scale(scalX,scalY,scalZ,r=True,p=centerPivet)
        
    def setCtrlColor(self,colors,objset):
        shapename=mc.listRelatives(objset,s=True)
        for i in shapename:
            mc.setAttr(str(i)+'.overrideEnabled',1)
            mc.setAttr(str(i)+'.overrideColor',colors)
    def setObjRef(self):
        selobj=mc.ls(sl=True)
        for i in selobj:
            shape=mc.listRelatives(i,s=True)
            for k in shape:
                mc.setAttr(str(k)+'.overrideEnabled',1)
                mc.setAttr(str(k)+'.overrideDisplayType',2)
                mc.setAttr(str(k)+'.overrideColor',17)
                
    def combineCurve(self):
        selobj=mc.ls(sl=True)
        childobj=selobj[1:]
        for i in childobj:
            childshape=mc.listRelatives(i,s=True)[0]
            mc.parent(childshape,selobj[0],add=True,s=True)
            mc.delete(i)
            
    def normalizeShapename(self):
        objsel=mc.ls(sl=True)
        for i in objsel:
            shapename=mc.listRelatives(i,s=True)[0]
            newshapename=str(i)+'Shape'
            mc.rename(shapename,newshapename)
    ############################################################################################################        
    #####-------------------------------------------------------------------------------------------------------
    def fixedCtrl(self,rivetObj):
        motherType=self.getObjType(rivetObj)
        
        if motherType=='kMesh'or motherType=='kNurbsSurface':
            obj=mc.ls(sl=True)
            inputmesh=rivetObj
            
            if motherType=='kMesh':
                
                mc.createNode('closestPointOnMesh',n='fixedNode')
            
            if motherType=='kNurbsSurface':
                
                mc.createNode('closestPointOnSurface',n='fixedNode')
                
            meshshape=mc.listRelatives(inputmesh,s=True)[0]
            meshMatrix=str(meshshape)+'.worldMatrix[0]'
            if motherType=='kMesh':
                meshout=str(meshshape)+'.outMesh'
            if motherType=='kNurbsSurface':
                meshout=str(meshshape)+'.local'
            follicleAll=[]
            
            if mc.objExists('follicle_grp'):
                pass
            else:
                mc.group(em=True,n='follicle_grp')
                
            for i in obj:
                folliclename=str(i)+'_follicleshape'
                mc.createNode('follicle',n=folliclename)
                follicleparent=mc.listRelatives(folliclename,p=True)[0]
                follicleparentname=str(i)+'_follicle'
                mc.rename(follicleparent,follicleparentname)
                
                mc.connectAttr(meshMatrix,str(folliclename)+'.inputWorldMatrix')
                if motherType=='kMesh':
                    mc.connectAttr(meshout,str(folliclename)+'.inputMesh')
                    matrixconnect=mc.listConnections('fixedNode.inMesh')
                    if matrixconnect==None:
                        mc.connectAttr(meshout,'fixedNode.inMesh')
                if motherType=='kNurbsSurface':
                    mc.connectAttr(meshout,str(folliclename)+'.inputSurface')
                    
                
                    matrixconnect02=mc.listConnections('fixedNode.inputSurface')
                    if matrixconnect02==None:
                        mc.connectAttr(meshout,'fixedNode.inputSurface')
                        print(1)
                    
         #      add a temporary group to connect it's translate to fixednode'inposition because of getting wrong location information if there are other groups above it
                
                mc.group(em=True,n='temporarygrp')
                mc.parentConstraint(i,'temporarygrp',maintainOffset=False)
         #########
               
                mc.connectAttr('temporarygrp.translate','fixedNode.inPosition')
                
                mc.connectAttr(str('fixedNode')+'.parameterU',str(folliclename)+'.parameterU')
                mc.connectAttr(str('fixedNode')+'.parameterV',str(folliclename)+'.parameterV')
                
                mc.connectAttr(str(folliclename)+'.outTranslate',str(follicleparentname)+'.translate')
                mc.connectAttr(str(folliclename)+'.outRotate',str(follicleparentname)+'.rotate')
                
                locparameterU=mc.getAttr(str(follicleparentname)+'.parameterU')
                locparameterV=mc.getAttr(str(follicleparentname)+'.parameterV')
                
                mc.disconnectAttr('fixedNode.parameterU',str(follicleparentname)+'.parameterU')
                mc.disconnectAttr('fixedNode.parameterV',str(follicleparentname)+'.parameterV')
                
                mc.setAttr('fixedNode.parameterU',locparameterU)
                mc.setAttr('fixedNode.parameterV',locparameterV)
                
                mc.parentConstraint(follicleparentname,i,maintainOffset=True)
                mc.disconnectAttr('temporarygrp.translate','fixedNode.inPosition')
                follicleAll.append(follicleparentname)
                mc.delete('temporarygrp')
                
            mc.parent(follicleAll,'follicle_grp')
            mc.delete('fixedNode')
        
        if motherType=='kNurbsCurve':
            curvename=rivetObj
            
            objsel=mc.ls(sl=True)
            shapecurve=mc.listRelatives(curvename,s=True)[0]
            
            num=0
            for i in objsel:
                namePoci=str(i)+'_poci'
                mc.createNode('pointOnCurveInfo',n=namePoci)[0]
                parameter=self.getParam(curvename , i)
                mc.connectAttr(str(shapecurve)+'.worldSpace',namePoci+'.inputCurve')
                mc.connectAttr(namePoci+'.result.position',str(i)+'.translate')
                mc.setAttr(namePoci+'.parameter',parameter)
        
    ##----------------------------------------------------------------------------------------------
    def getSpace(self,obj):
            '''get one object's worldSpace value'''
            objT = mc.xform(obj,q=1,t=1,ws=1)
            objR = mc.xform(obj,q=1,ro=1,ws=1)
            aboutObjDate = objT + objR
            return aboutObjDate
    
    
    def node_by_name(self,name, root = om.MObject.kNullObj):
            dagiter = om.MItDag(om.MItDag.kDepthFirst)
            if not root is om.MObject.kNullObj:
                dagiter.reset(root)
            while not dagiter.isDone():
                pf = om.MFnDagNode(dagiter.currentItem())
                if pf.name() == name:
                    return dagiter.currentItem()
                dagiter.next()
            return om.MObject.kNullObj
    
    def getParam(self,crv , obj):
    
            curveshape = mc.listRelatives(crv,s=True)
            objspace = self.getSpace(obj)
    
            curveObj = self.node_by_name(curveshape[0])
            curveFn = om.MFnNurbsCurve(curveObj)
            mpoint = om.MPoint( objspace[0],objspace[1],objspace[2],1.0)
            nearestPoint = curveFn.closestPoint(mpoint,None,0.0001,om.MSpace.kTransform )
            u_util = om.MScriptUtil()
            uPtr = u_util.asDoublePtr()
            curveFn.getParamAtPoint(nearestPoint,uPtr,om.MSpace.kTransform)
            u1 = u_util.getDouble(uPtr)
            return u1
            
    ####################################################################################################
    #------------------------------- create inverseMatrix   ------------------------------------------
    def createRecerseJnt(self,stept):
        
        seleJnt=mc.ls(sl=True)
        
        for k in seleJnt:
            mc.select(k)
            for i in range(stept):
                mc.pickWalk(d='up')
            
            parentname=mc.ls(sl=True)[0]
            splitname=str(k).split('_')    
            reversename=str(k).replace(splitname[-1],'reverse')
            
            mc.duplicate(k,n=reversename)
            mc.setAttr(str(reversename)+'.visibility',0)
            if stept>1:
                mc.parent(reversename,parentname)
    def conneReverseAttr(self,skinname,IsAllCluters):
        
        jntConnectAll=[]
        worldMatrixAttr=[]
        
        # skinname='skinCluster6'
        connectAttrs=mc.listConnections(skinname,s=True,p=True,c=True,scn=True)
        for m in connectAttrs:
            if 'worldMatrix' in m:
                worldMatrixAttr.append(m)
        for i in worldMatrixAttr:
            ojbConnect=str(i).split('.')[0]
            jntConnectAll.append(ojbConnect)
            
            if IsAllCluters == 1:
    
                connectedMatrixAttr=mc.listConnections(i,d=True,p=True)
    
          
                for k in connectedMatrixAttr:
                
            
                    bindAttr=str(k).replace('matrix','bindPreMatrix')
                    splitname=str(ojbConnect).split('_')
                    reversename=str(ojbConnect).replace(splitname[-1],'reverse')
            
                    attrIsConnect=mc.listConnections(bindAttr,s=True)
                    if attrIsConnect==None: 
                        mc.connectAttr(str(reversename)+'.worldInverseMatrix[0]',bindAttr)
                        print(1)
            if IsAllCluters == 0:
                connectedMatrixAttrs=mc.listConnections(i,d=True,p=True)
                
                for cmas in connectedMatrixAttrs:
                    if skinname in cmas:
                        connectedMatrixAttr=cmas
    
                orgbindAttr=str(connectedMatrixAttr).replace('matrix','bindPreMatrix')
                replacename=str(connectedMatrixAttr).split('.')[0]
                bindAttr=str(orgbindAttr).replace(replacename,skinname)
                
                splitname=str(ojbConnect).split('_')
                reversename=str(ojbConnect).replace(splitname[-1],'reverse')
    
                attrIsConnect=mc.listConnections(bindAttr,s=True)
                if attrIsConnect==None: 
                    mc.connectAttr(str(reversename)+'.worldInverseMatrix[0]',bindAttr)
                    print(str(reversename)+'.worldInverseMatrix[0]'+'-----------'+bindAttr)
        sys.stdout.write('" ok,,inverseMatrix has connected the skinCluster!! "')
        

    def referenceScence(self,fileName):
        
        referenceMel='referenceFile "'+fileName+'" "Best Guess";'
        mel.eval(referenceMel)
        
    #############################################################################################
    #-------------------------   setDrivenKey   -------------------------------------------------
    def setDrivenKey(self,driver,driven,driverV=0,drivenV=[]):
        drivenAt=[driven+'.translateX',driven+'.translateY',driven+'.translateZ',driven+'.rotateX',driven+'.rotateY',driven+'.rotateZ',]
        for k in range(6):
            mc.setDrivenKeyframe(drivenAt[k], cd=driver,dv=driverV,v=drivenV[k])
    ####          list  SDKenAttr          
    def listSDKerAttr(self,driverAttr):

        animaCurve=mc.listConnections(driverAttr,d=True,t='animCurveUL')

        if animaCurve==None:
            
            mc.textScrollList('SDKenAttrlist',ra=True,e=True)
            sys.stdout.write('there is no any setDrivenKey object')
        else:
            SDKenObj=[]
            for i in animaCurve:
                blendWeightNode=mc.listConnections(str(i)+'.output',d=True)[0]
                
                nodeblend=mc.nodeType(blendWeightNode)
                if nodeblend=='blendWeighted':
                
                    childNode=mc.listConnections(str(blendWeightNode)+'.output',d=True) 
            
                    for m in childNode:
                        
                        typenode=mc.nodeType(m)
                        
                        if typenode=='transform' or 'joint':
                            if m in SDKenObj:
                                pass
                            else:
                                SDKenObj.append(m)
                else:
                    if blendWeightNode in SDKenObj:
                            pass
                    else:
                        SDKenObj.append(blendWeightNode)

            mc.textScrollList('SDKenAttrlist',ra=True,e=True)
            mc.textScrollList('SDKenAttrlist',append=SDKenObj,e=True)
    ########  add this def on 2013/7/5
    
    def RemoveSDKenAttr(self,driverAttr,driven):
        animaCurve=mc.listConnections(driverAttr,d=True,t='animCurve')
        blendWeightNode=mc.listConnections(driven,s=True)
        
        for i in blendWeightNode:
            nodeblend=mc.nodeType(i)
            if nodeblend=='blendWeighted':
                aniCurveULs=mc.listConnections(i,s=True)
                for k in aniCurveULs:
                    if k in animaCurve:
                        mc.delete(k)
                    else:
                        pass
            elif nodeblend=='unitConversion':
                connectObj=mc.listConnections(i,s=True)

                for ani in connectObj:
                    nodeblend02=mc.nodeType(ani)
                    if nodeblend02=='blendWeighted':

                        unitCon=mc.listConnections(ani,s=True)

                        for k in unitCon:

                            aniCurves=mc.listConnections(k,s=True)

                            for uni in aniCurves:

                                if uni in animaCurve:
                                    mc.delete(uni)

                                else:
                                    pass
    ###########       add this def on 2013/7/5 18:04
    def listEmotionBase(self):
        seleMenue=mc.optionMenu('SDKbridgemenu',q=True,sl=True)
        if seleMenue == 2:
            mc.textScrollList('emotionBAselist',e=True,append=['L_Brow_UP','L_Brow_UP','L_UpperLid_Close','L_LowerLid_Close','L_LowerLid_Open','L_EyeOribic'])
        